"""GTest 扩展的 IR 节点定义

提供 GTest 单元测试的专用 IR 节点类型。
"""

from dataclasses import dataclass, field
from mcpy.ir import IRFunctionNode


@dataclass
class IRGTestFunctionNode(IRFunctionNode):
    """GTest 测试函数 IR 节点

    继承自 IRFunctionNode，但使用特殊的 node_type 和渲染逻辑
    """

    node_type: str = "gtest_function"

    macro_type: str = field(default="TEST")  # "TEST" 或 "TEST_F"
    test_suite: str = field(default="DefaultTestSuite")
    test_name: str = field(default="")

    def __post_init__(self):
        """初始化后处理"""
        if not self.test_name:
            self.test_name = self.name

    def render(self, context: dict) -> str:
        """渲染 GTest 宏代码

        Args:
            context: 渲染上下文，可能包含 type 等信息
        """
        # 从上下文中获取文件类型
        type = context.get("type")
        # 在头文件中，GTest 宏不应该被渲染，返回空字符串
        if type == "header":
            return ""

        # 在源文件中，生成完整的 GTest 宏
        # 生成宏声明
        macro_code = f"{self.macro_type}({self.test_suite}, {self.test_name})"

        # 生成函数体
        if hasattr(self, "body") and self.body:
            from mcpy.codegen.core.generator import get_global_generator
            from mcpy.codegen.core.context import CodeGenContext

            ir_module = self.get_ir_module()
            generator = get_global_generator()

            # 创建一个新的代码生成上下文，并正确设置 current_node
            gen_context = CodeGenContext(ir_module=ir_module)
            gen_context.current_node = self  # 设置当前节点为函数节点本身

            body_code = generator.generate_statements(
                self.body.statements,
                return_type="void",  # GTest 函数返回 void
                context=gen_context,  # 传递包含 current_node 的上下文
            )
        else:
            body_code = "// Empty test body"

        # 组合完整的测试函数代码
        full_code = (
            f"{macro_code} {{\n    {body_code.replace(chr(10), chr(10) + '    ')}\n}}"
        )

        return full_code


@dataclass
class IRGTestFixtureFunctionNode(IRGTestFunctionNode):
    """GTest 测试夹具函数 IR 节点

    用于 TEST_F 宏的测试函数
    """

    node_type: str = "gtest_fixture_function"
    macro_type: str = field(default="TEST_F")

    def render(self, context: dict) -> str:
        """渲染 GTest 测试夹具宏

        Args:
            context: 渲染上下文，可能包含 type 等信息

        Returns:
            渲染后的 C++ 代码
        """
        # 从上下文中获取文件类型
        type = context.get("type")
        if type == "header":
            return ""

        # 在源文件中，生成完整的 GTest 宏
        # 生成宏声明
        macro_code = f"{self.macro_type}({self.test_suite}, {self.test_name})"

        # 生成函数体
        if hasattr(self, "body") and self.body:
            from mcpy.codegen.core.generator import get_global_generator
            from mcpy.codegen.core.context import CodeGenContext

            ir_module = self.get_ir_module()
            generator = get_global_generator()

            gen_context = CodeGenContext(ir_module=ir_module)
            gen_context.current_node = self  # 设置当前节点为函数节点本身

            # 使用正确的 emit 方法参数
            body_code = generator.generate_statements(
                self.body.statements,
                return_type="void",  # GTest 函数返回 void
                context=gen_context,  # 传递包含 current_node 的上下文
            )

            # 修复 this. 到 this-> 的转换
            # 在 TEST_F 宏中，this 是指针，应该使用 this->
            body_code = body_code.replace("this.", "this->")
        else:
            body_code = "// Empty test body"

        # 组合完整的测试函数代码
        full_code = (
            f"{macro_code} {{\n    {body_code.replace(chr(10), chr(10) + '    ')}\n}}"
        )

        return full_code
